#include "MyOCL.h"

// system of linear algebraic equations
class SLAE : public MyOCL
{
private:
	cl_float * pMatrix;			// the matrix of linear system
	cl_float * pVector;			// the right parts of the linear system
	cl_float * pResult;			// the result vector on GPU
	cl_uint size;				// size of the initial matrix and vector
	cl_float solvePrecision;	// solve precision
	cl_float * pNextSolution;	// next solution

	long float * pResultCPU;	// the result vector on CPU

	// the memory buffer that is used as input/output for OpenCL kernel 
	cl_mem	pMatrixBuffer;			// for pMatrix
	cl_mem	pVectorBuffer;			// for pVector
	cl_mem	pResultBuffer;			// for pResult
	cl_mem	pNextSolutionBuffer;	// for pNextSolution

	//cl_context context;
	//cl_device_id * devices;
	//cl_command_queue commandQueue;

	cl_program program;
	// this program uses only one kernel and this serves as a handle to it 
	cl_kernel kernel;

	// time on GPU
	double startGPU;
	double endGPU;

	// time on CPU
	double startCPU;
	double endCPU;

	// Initialize CL 
	void initializeCL(void);
	// Initialize Host application 
	void initializeHost(void);
	// releases OpenCL resources
	void cleanupCL(void);
	// releases program's resources 
	void cleanupHost(void);
	
public:
	double time;
	SLAE(cl_uint sizeVector, float precision);
	~SLAE();
	// run kernel on cl
	void runCLKernels(void);
	void printTest();

	// Jacobi on CPU
	void Jacobi();
	// timer on GPU
	double getTimeGPU() {return endGPU - startGPU;}
	double getTimeCPU() {return endCPU - startCPU;}

};